package com.wjc.network

import com.wjc.network.errorhandler.ExceptionHandle
import com.wjc.network.errorhandler.HttpErrorHandler
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.core.SingleObserver
import io.reactivex.rxjava3.core.SingleTransformer
import io.reactivex.rxjava3.functions.Function
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.logging.Level

/**
 * ClassName: com.wjc.network
 * Description: 创建、配置 Retrofit
 * JcChen on 2021.04.16.17:08
 */
object RetrofitFactory {
    private const val DEFAULT_TIMEOUT = 60000
    private var mNetworkInfo: INetworkRequiredInfo? = null


    fun init(networkInfo: INetworkRequiredInfo) {
        mNetworkInfo = networkInfo
    }

    fun <T> getService(service: Class<T>): T {
        return fetchRetrofit.create(service)
    }

    fun <T> applySchedulers(observer: SingleObserver<T>): SingleTransformer<T, T> {
        return SingleTransformer { upstream ->
            val observable = upstream
                .compose(ioToMainThread())
                .map(getErrorMsg())
                .onErrorResumeNext( Function {
                    Single.error(ExceptionHandle.handleException(it))
                }) as Single<T>
//                .onErrorResumeNext(HttpErrorHandler<T>()) as Single<T>  // 发送错误信息到onNext
            observable.subscribe(observer)
            observable
        }
    }

    // 创建OkHttp
    private val okHttpClient: OkHttpClient
        get() {
            return OkHttpClient.Builder()
                .readTimeout(DEFAULT_TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
                .connectTimeout(DEFAULT_TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
                .addInterceptor(getLogInterceptor())
                .hostnameVerifier { _, _ -> true }    //信任所有的证书
                .cache(getCache())
                .build()
        }

    // 创建 Retrofit 对象
    private val fetchRetrofit: Retrofit
        get() {
            return Retrofit.Builder()
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .baseUrl(mNetworkInfo!!.fetchBaseUrl())
                .build()
        }

    //非200，抛出异常
    private fun <T> getErrorMsg(): Function<T, T> {
        return Function<T, T> { response ->
            if (response is ResponseResult<*> && response.code != 200) {
                throw ExceptionHandle.ServerException(response.code, response.message)
            }
            response
        }
    }

    /**
     * 接口线程调度
     *
     * @param <T>
     * @return
    </T> */
    fun <T> ioToMainThread(): SingleTransformer<T, T> {
        return SingleTransformer { upstream ->
            upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
        }
    }

    // 获取日志拦截器
    private fun getLogInterceptor(): Interceptor {
        //http log 拦截器
        return HttpLoggingInterceptor("OkHttp_Log").apply {
            setPrintLevel(HttpLoggingInterceptor.Level.BODY)
            setColorLevel(Level.INFO)
        }
    }


    // 获取缓存方式
    private fun getCache(): Cache {
        //缓存50Mb
        return Cache(
            File(mNetworkInfo!!.fetchApplicationContext().cacheDir, "cache"),
            1024 * 1024 * 50
        )
    }

}